package com.rico.gallery.socket;

import com.rico.gallery.message.DeviceLoginMessage;
import com.rico.gallery.device.DeviceInfo;
import com.rico.gallery.message.IMessage;
import com.rico.gallery.message.MessageType;
import com.rico.gallery.message.MsgMessage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ServerConnectionManager implements MessageHandler{
    private static ServerConnectionManager instance;

    private SocketClient serverSocketClient=null;
    private String serverHost="113.118.25.195";
    //private String serverHost="wonder123.imwork.net";

    private int serverPort=5002;

    private String sessionId;

    private DeviceInfo deviceInfo;

    private List<MessageHandler> messageHandleres=new ArrayList<>();

    private ServerConnectionManager(){
    }

    public static ServerConnectionManager getInstance(){
        if(instance==null){
            instance=new ServerConnectionManager();
        }
        return instance;
    }

    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    public MsgMessage connectServer(DeviceInfo deviceInfo) throws IOException {
       this.deviceInfo=deviceInfo;
       return connectServer();

    }

    public MsgMessage connectServer() throws IOException {
        DeviceLoginMessage deviceConnectMessage=new DeviceLoginMessage();
        deviceConnectMessage.setDeviceId(deviceInfo.getDeviceId());
        deviceConnectMessage.setLocalIP(deviceInfo.getLocalIP());
        deviceConnectMessage.setClientType(1);
        deviceConnectMessage.setLocalPort(deviceInfo.getLocalPort());
        MsgMessage msgMessage= (MsgMessage)this.sendMessageAndWaitResponse(deviceConnectMessage);
        return msgMessage;
    }


    private void ensure() throws IOException {
        if(serverSocketClient==null) {
            serverSocketClient = new SocketClient(serverHost, serverPort);
        }
        if(!serverSocketClient.isConnected()) {
            serverSocketClient.connect();
            serverSocketClient.setMessageHandler(this);
        }
    }

    public synchronized void sendMessage(final IMessage message) throws IOException {
        message.setSessionId(sessionId);
        ensure();
        serverSocketClient.sendMessage(message);

    }

    public IMessage sendMessageAndWaitResponse(IMessage message,Integer waitTimeOut) throws IOException {
        message.setSessionId(sessionId);
        ensure();
        return serverSocketClient.sendMessageAndWaitResponse(message,waitTimeOut);
    }

    public synchronized IMessage sendMessageAndWaitResponse(IMessage message) throws IOException {
       return sendMessageAndWaitResponse(message,15000);
    }


    @Override
    public void onMessageReceived(SocketConnection socketThread, IMessage message) {
        for(MessageHandler item:messageHandleres){
            item.onMessageReceived(socketThread,message);
        }
        this.sessionId=message.getSessionId();
    }

    @Override
    public void onReceivedMessageError(SocketConnection socketThread, Exception e) {
        synchronized (this) {
            this.notifyAll();
        }
    }

    public void addMessageHandler(MessageHandler messageHandler){
        if(!messageHandleres.contains(messageHandler)) {
            messageHandleres.add(messageHandler);
        }
    }

    public SocketClient getServerSocketClient() {
        return serverSocketClient;
    }

    public void setServerSocketClient(SocketClient serverSocketClient) {
        this.serverSocketClient = serverSocketClient;
    }


    public void startTestThread(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){

                    if(serverSocketClient!=null&&serverSocketClient.getSocketConnection()!=null&&System.currentTimeMillis()-serverSocketClient.getSocketConnection().getLastActiveTime()>3000){
                        MsgMessage msgMessage=new MsgMessage(MessageType.TEST,"");
                        msgMessage.setMessageId(System.currentTimeMillis());
                        try {
                            if(deviceInfo!=null&&sessionId==null){
                                MsgMessage message=connectServer();
                                if(message.getMessageType()==MessageType.SUCCESS){
                                    sessionId=message.getSessionId();
                                }
                            }else {
                                sendMessage(msgMessage);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}
